import 'package:ball_lion/module/expert/items/expert_logo.dart';
import 'package:ball_lion/module/match_detail/live/live_plan_popup.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:ball_lion/module/live/live_message_logic.dart';
import 'package:ball_lion/entity/live/live_detail_entity.dart';
import 'package:ball_lion/module/live/items/live_ads.dart';
import 'package:visibility_detector/visibility_detector.dart';
import 'package:ball_lion/entity/live/ali_live_message.dart';
import 'package:ball_lion/entity/other/resource_entity.dart';
import 'package:ball_lion/resources/colours.dart';
import 'package:ball_lion/utils/ali_message.dart';
import 'package:ball_lion/routes/routes.dart';
import 'package:ball_lion/utils/user.dart';
import 'package:ball_lion/utils/utils.dart';
import 'package:ball_lion/widgets/circular.dart';
import 'package:ball_lion/widgets/base/wqs_text.dart';
import 'package:ball_lion/widgets/scroll_bar.dart';
import 'live_text_field.dart';

enum MessageScene { match, normal, push }

class LiveMessageList extends StatefulWidget {
  const LiveMessageList(
      {super.key,
      required this.liveDetail,
      this.newMessageCount,
      this.sportsId = 1,
      this.scene = MessageScene.normal});

  final LiveDetailEntity? liveDetail;
  final MessageScene scene;
  final int sportsId;
  final ValueChanged<int>? newMessageCount;

  @override
  State<LiveMessageList> createState() => _LiveMessageListState();
}

class _LiveMessageListState extends State<LiveMessageList> {
  late final LiveMessageLogic logic;

  double get messageWidth {
    switch (widget.scene) {
      case MessageScene.match:
        return context.width - 40;
      case MessageScene.normal:
      case MessageScene.push:
        return Get.width * (299 / 375);
    }
  }

  @override
  void initState() {
    logic = Get.put(
        LiveMessageLogic(liveDetail: widget.liveDetail, scene: widget.scene),
        tag: "${widget.liveDetail?.liveId}",
        permanent: true);
    logic.scrollController.addListener(() {
      if (logic.scrollController.position.extentAfter > 100 &&
          logic.showMessage == false) {
        logic.showMessage = true;
        widget.newMessageCount?.call(logic.messageCount);
        setState(() {});
      } else if (logic.scrollController.position.extentAfter < 100 &&
          logic.showMessage == true) {
        logic.showMessage = false;
        widget.newMessageCount?.call(logic.messageCount);
        setState(() {});
      }
      if (logic.scrollController.offset >= 0 &&
          logic.scrollController.offset <= 10) {
        setState(() {});
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    Get.delete<LiveMessageLogic>(
        tag: "${widget.liveDetail?.liveId}", force: true);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<LiveMessageLogic>(
        tag: "${widget.liveDetail?.liveId}",
        initState: (state) => logic.userStore = User.info,
        builder: (logic) {
          return VisibilityDetector(
            key: const Key("live_message"),
            onVisibilityChanged: (VisibilityInfo info) {
              if (!info.visibleBounds.isEmpty) {
                if (logic.userStore?.id != User.info?.id) {
                  AliMessage().enterGroup(widget.liveDetail?.chatGroupId ?? "");
                  logic.userStore = User.info;
                }
              }
            },
            child: Stack(
              children: [
                Column(
                  children: [
                    if (logic.chatInfo?.notice.hasValue == true)
                      SizedBox(
                        width: Get.width,
                        child: ScrollBoard(
                          type: "chat",
                          resource: [
                            ResourceEntity(
                                title: logic.chatInfo?.notice,
                                href: logic.chatInfo?.noticeHref)
                          ],
                          margin: EdgeInsets.fromLTRB(
                              widget.scene == MessageScene.normal ? 0 : 8,
                              widget.scene == MessageScene.normal
                                  ? MediaQuery.of(context).padding.top + 44 + 4
                                  : 8,
                              widget.scene == MessageScene.normal ? 0 : 8,
                              0),
                          canTap: true,
                          gradient: widget.scene == MessageScene.normal
                              ? LinearGradient(colors: [
                                  Colours.black.withOpacity(0),
                                  Colours.black.withOpacity(0.2)
                                ], stops: [
                                  0.1,
                                  0.55
                                ])
                              : null,
                        ),
                      ),
                    Expanded(
                      child: Stack(
                        alignment: Alignment.bottomLeft,
                        children: [
                          Positioned.fill(
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              mainAxisAlignment: MainAxisAlignment.end,
                              children: [
                                if (widget.scene != MessageScene.match)
                                  giftList(),
                                messageSizedBox(
                                    child: MediaQuery.removePadding(
                                        removeTop: true,
                                        context: context,
                                        child: ShaderMask(
                                            shaderCallback: (Rect bounds) =>
                                                LinearGradient(
                                                  colors: [
                                                    logic.scrollController
                                                                    .offset >
                                                                0 &&
                                                            widget.scene !=
                                                                MessageScene
                                                                    .match
                                                        ? Colours.transparent
                                                        : Colours.white,
                                                    Colours.white
                                                  ],
                                                  stops: const [0, 0.2],
                                                  begin: Alignment.topCenter,
                                                  end: Alignment.bottomCenter,
                                                ).createShader(bounds),
                                            child: ScrollConfiguration(
                                                behavior: const ScrollBehavior()
                                                    .copyWith(
                                                        overscroll: false),
                                                child: ListView.builder(
                                                    controller:
                                                        logic.scrollController,
                                                    itemCount:
                                                        logic.messages.length,
                                                    shrinkWrap: true,
                                                    itemBuilder:
                                                        (context, index) =>
                                                            message(index))))))
                              ],
                            ),
                          ),
                          if (logic.showMessage && !logic.inScroll)
                            Positioned(
                                left: 8, bottom: 12, child: backWidget()),
                          if (widget.scene != MessageScene.push)
                            Positioned(
                                right: 8,
                                bottom: 16 + 92,
                                child: LiveAds(scene: widget.scene)),
                          if (widget.scene == MessageScene.match) ...[
                            Positioned(top: 8, right: 9, child: focus()),
                            Positioned(
                                top: 42, left: 0, right: 0, child: giftList())
                          ]
                        ],
                      ),
                    ),
                    if (logic.initialized)
                      SafeArea(
                        top: false,
                        child: LiveTextField(widget.liveDetail?.liveId ?? 0,
                            sportsId: widget.sportsId, scene: widget.scene),
                      )
                  ],
                ),
                if (logic.plan != null &&
                    logic.showPlan &&
                    !logic.focus.hasFocus &&
                    (logic.chatInfo?.plan ?? false) &&
                    widget.scene != MessageScene.push)
                  Positioned(
                      bottom: 48,
                      left: 8,
                      right: 8,
                      child: LivePlanPopup(
                        plan: logic.plan,
                        isHost:
                            logic.plan?.expertId == logic.liveDetail?.expertId,
                        onTap: (value) {
                          Utils.onEvent("liveroom_plan_recommend");
                          if (value) {
                            Get.toNamed(Routes.viewpoint,
                                arguments: logic.plan?.planId);
                            logic.showPlan = false;
                          } else {
                            logic.showPlan = false;
                          }
                        },
                      )),
              ],
            ),
          );
        });
  }

  Widget message(int index) {
    AliLiveMessage msg = logic.messages[index];
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Circular(
          radius: 12,
          color: widget.scene == MessageScene.match
              ? null
              : Colors.black.withOpacity(1 / 3),
          padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
          margin: const EdgeInsets.symmetric(vertical: 3, horizontal: 8),
          child: RichText(
              text: TextSpan(
                  style: TextStyle(
                      fontSize: widget.scene == MessageScene.push ? 16 : 14,
                      fontWeight: FontWeight.w500),
                  children: [
                if (msg.status == MessageType.sendMessage)
                  TextSpan(
                      text: "${msg.userName}：",
                      style: TextStyle(
                        color: widget.scene == MessageScene.match
                            ? Colours.grey99
                            : Colours.orangeFCDDA1,
                      ),
                      recognizer: TapGestureRecognizer()
                        ..onTap = () {
                          if (widget.scene == MessageScene.push) {
                            logic.muteUser(msg);
                          }
                        })
                else if (msg.status == MessageType.joinGroup ||
                    msg.status == MessageType.focus ||
                    msg.status == MessageType.gift ||
                    msg.status == MessageType.other)
                  if (msg.userName.hasValue)
                    TextSpan(
                        text: "${msg.userName} ",
                        style: TextStyle(
                          color: widget.scene == MessageScene.match
                              ? Colours.grey99
                              : Colours.orangeFCDDA1,
                        ),
                        recognizer: TapGestureRecognizer()
                          ..onTap = () {
                            if (widget.scene == MessageScene.push) {
                              logic.muteUser(msg);
                            }
                          }),
                TextSpan(
                    text: msg.message,
                    style: TextStyle(
                      color: widget.scene == MessageScene.match
                          ? msg.status?.matchColor
                          : msg.status?.color,
                    ),
                    recognizer: TapGestureRecognizer()
                      ..onTap = () {
                        if (widget.scene == MessageScene.push) {
                          logic.deleteMessage(msg);
                        }
                      })
              ])),
        ),
      ],
    );
  }

  Widget giftList() {
    return AnimatedList(
        key: logic.listKey,
        padding: EdgeInsets.zero,
        physics: const NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        itemBuilder: (context, index, animation) =>
            logic.gift(index, animation));
  }

  Widget backWidget() {
    return GestureDetector(
      onTap: logic.scrollToEnd,
      child: Container(
        height: 26,
        alignment: Alignment.center,
        clipBehavior: Clip.antiAlias,
        padding: const EdgeInsets.symmetric(horizontal: 8),
        decoration: BoxDecoration(
            color: Colours.white, borderRadius: BorderRadius.circular(23)),
        child: QsText(
          logic.messageCount == 0
              ? "回到底部"
              : "${logic.messageCount < 100 ? logic.messageCount : "99+"}条新消息",
          needCenter: true,
          fontSize: 12,
          color: const Color(0xFFFF8730),
        ),
      ),
    );
  }

  Widget messageSizedBox({required Widget child}) {
    switch (widget.scene) {
      case MessageScene.match:
        return Expanded(
          child: SizedBox(
            width: Get.width - 67,
            child: child,
          ),
        );
      case MessageScene.normal:
      case MessageScene.push:
        return SizedBox(
          width: Get.width * (299 / 375),
          height: 252,
          child: child,
        );
    }
  }

  Widget focus() {
    return Container(
      width: 56,
      clipBehavior: Clip.antiAlias,
      decoration: const BoxDecoration(
          color: Colours.white,
          borderRadius: BorderRadius.vertical(
              top: Radius.circular(28), bottom: Radius.circular(8))),
      child: Column(
        children: [
          SizedBox(
              height: 62,
              child: Stack(
                alignment: AlignmentDirectional.center,
                children: [
                  GestureDetector(
                      onTap: () {
                        Utils.onEvent('liveroom_expert_view');
                        Get.toNamed(Routes.userPage,
                            arguments: logic.liveDetail?.expertId,
                            parameters: {"type": "2"});
                      },
                      child: ExpertLogo(
                          logo: logic.liveDetail?.expertLogo, inLive: true)),
                  Positioned(
                    bottom: 0,
                    child: GestureDetector(
                      onTap: logic.toFocus,
                      child: Container(
                        width: 40,
                        height: 24,
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                            color: logic.liveDetail?.isFocus == 1
                                ? Colours.greyDD
                                : null,
                            borderRadius: BorderRadius.circular(18),
                            gradient: logic.liveDetail?.isFocus == 1
                                ? null
                                : const LinearGradient(
                                    colors: [
                                      Color(0xFFF54D4F),
                                      Color(0xFFF53C6A)
                                    ],
                                  )),
                        child: QsText(
                          logic.liveDetail?.isFocus == 1 ? "已关注" : "+关注",
                          fontSize: 10,
                          color: logic.liveDetail?.isFocus == 1
                              ? Colours.grey99
                              : Colours.white,
                        ),
                      ),
                    ),
                  )
                ],
              )),
          QsText(logic.liveDetail?.expertName ?? "",
                  maxLines: 1,
                  textAlign: TextAlign.center,
                  needCenter: true,
                  fontSize: 10,
                  fontWeight: FontWeight.w500)
              .paddingSymmetric(horizontal: 2, vertical: 4)
        ],
      ),
    );
  }
}
